function FSMStateGameEnded(gameArbiter, gameArea, cells, gameOutcomeDiv) {
	this.fsmStateChoseNextPlayer = null;
	this.startButtonPushed = false;
	this.initLoading = false;
	this.gameArbiter = gameArbiter;
	this.gameArea = gameArea;
	this.cells = cells;
	this.gameOutcomeDiv = gameOutcomeDiv;
};

FSMStateGameEnded.prototype = Object.create(FSMState.prototype);
FSMStateGameEnded.prototype.constructor = FSMStateGameEnded;

FSMStateGameEnded.prototype.onProcessInput = function(inputEvent, fsmContext) {
	if(inputEvent instanceof GameStartEvent) {
		fsmContext["nextPlayerOwner"] = inputEvent.firstPlayerOwner;
		this.startButtonPushed = true;
	}
};

FSMStateGameEnded.prototype.onUpdateState = function(fsmContext) {
	if(this.updatedGraphics) {
		this.updatedGraphics = true;
		return this;
	}
	
	if(!this.startButtonPushed) {
		return this;
	} else {
		$("#firstPlayerOwnerSelect").attr("disabled", "disabled");
		$("#startGameButton").attr("disabled", "disabled");
		if(!this.initLoading) {
			for(var i = 0; i < this.cells.length; i++) {
				var cell = this.cells[i];
				cell.tokenType = TokenType.NONE;
				cell.setInactive(true);
			}
			this.gameArea.setLoading(true);
			this.initLoading = true;
			this.gameOutcomeDiv.html(" ");
			return this;
		} else {
			var st = new Date().getTime();
			this.gameArbiter.startNewGame(fsmContext["nextPlayerOwner"]);
			var et = new Date().getTime();
			DEBUG_CONSOLE.clear();
			DEBUG_CONSOLE.toConsole("Created game states tree containing " + this.gameArbiter.gameStatesTree.nodesCount + " nodes (excluding empty board node) in " + (et-st)/1000 + " seconds");
			DEBUG_CONSOLE.toConsole("Of these, " + this.gameArbiter.gameStatesTree.leafNodesScoredCount + " (leaf) nodes were scored based on their (game-ending) board state");
			DEBUG_CONSOLE.toConsole("Also, " + this.gameArbiter.gameStatesTree.intermediaryNodesScoredCount + " (non-leaf) nodes were scored based on their descendants");
			DEBUG_CONSOLE.toConsole("");
			DEBUG_CONSOLE.toConsole("CPU has  " + this.gameArbiter.gameStatesTree.cpuWinsCount + " winning games");
			DEBUG_CONSOLE.toConsole("Human player has  " + this.gameArbiter.gameStatesTree.humanWinsCount + " winning games");
			DEBUG_CONSOLE.toConsole("Games ending in a draw:  " + this.gameArbiter.gameStatesTree.drawsCount);
			DEBUG_CONSOLE.toConsole("");
			DEBUG_CONSOLE.toConsole("Check win status average time " +
					(this.gameArbiter.gameStateManager.checkWinStatusCallsTimeMs / this.gameArbiter.gameStateManager.checkWinStatusCallsCount) + " ms.");
						
			this.startButtonPushed = false;
			this.initLoading = false;
			this.gameArea.setLoading(false);
			for(var i = 0; i < this.cells.length; i++) {
				var cell = this.cells[i];
				cell.setInactive(false);
			}
			return this.fsmStateChoseNextPlayer;
		}		
	}
};